﻿#region << 文件说明 >>
/*----------------------------------------------------------------
 * 命名空间：Vampirewal.Core.WPF.Theme.CustomControl.UGrid
 * 唯一标识：996d1324-72e4-47c3-bee1-7f33d6c8e43e
 * 文件名：UGrid
 * 
 * 创建者：杨程
 * 电子邮箱：235160615@qq.com
 * 创建时间：2025/6/25 10:57:44
 * 版本：V1.0.0
 * 描述：高性能网格容器
 *
 * ----------------------------------------------------------------
 * 修改人：
 * 时间：
 * 修改说明：
 *
 * 版本：V2.0.0
 *----------------------------------------------------------------*/
#endregion << 文件说明 >>

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace Vampirewal.Core.WPF.Theme;

/// <summary>
/// 高性能网格容器
/// </summary>
public class UGrid : Canvas
{
    #region 构造方法
    public UGrid()
    {
        // 设置背景透明（由自定义渲染处理）
        Background = Brushes.Transparent;

        // 初始化重绘计时器
        _redrawTimer = new DispatcherTimer
        {
            Interval = TimeSpan.FromMilliseconds(150),
            IsEnabled = false
        };
        _redrawTimer.Tick += OnRedrawTimerTick;

        // 监听尺寸变化
        SizeChanged += UGrid_SizeChanged;

        // 启用网格线吸附
        IsSnapToGrid = true;
        SnapDistance = 8;
    }

    private void UGrid_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        // 当尺寸变化时，启动延迟重绘
        if (!_redrawTimer.IsEnabled)
        {
            _redrawTimer.IsEnabled = true;
        }
    }
    #endregion

    #region 依赖属性
    /// <summary>
    /// 是否启用网格吸附
    /// </summary>
    public bool IsSnapToGrid
    {
        get { return (bool)GetValue(IsSnapToGridProperty); }
        set { SetValue(IsSnapToGridProperty, value); }
    }
    public static readonly DependencyProperty IsSnapToGridProperty =
        DependencyProperty.Register("IsSnapToGrid", typeof(bool), typeof(UGrid),
        new PropertyMetadata(true));

    /// <summary>
    /// 网格吸附距离
    /// </summary>
    public double SnapDistance
    {
        get { return (double)GetValue(SnapDistanceProperty); }
        set { SetValue(SnapDistanceProperty, value); }
    }
    public static readonly DependencyProperty SnapDistanceProperty =
        DependencyProperty.Register("SnapDistance", typeof(double), typeof(UGrid),
        new PropertyMetadata(8.0));

    public int GridSize
    {
        get { return (int)GetValue(GridSizeProperty); }
        set { SetValue(GridSizeProperty, value); }
    }
    public static readonly DependencyProperty GridSizeProperty =
        DependencyProperty.Register("GridSize", typeof(int), typeof(UGrid),
        new PropertyMetadata(8, OnGridSizeChanged, CoerceGridSize));

    public Brush ColorLight
    {
        get { return (Brush)GetValue(ColorLightProperty); }
        set { SetValue(ColorLightProperty, value); }
    }
    public static readonly DependencyProperty ColorLightProperty =
        DependencyProperty.Register("ColorLight", typeof(Brush), typeof(UGrid),
        new PropertyMetadata(new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF2D2D2D")), OnGridSizeChanged));

    public Brush ColorDark
    {
        get { return (Brush)GetValue(ColorDarkProperty); }
        set { SetValue(ColorDarkProperty, value); }
    }
    public static readonly DependencyProperty ColorDarkProperty =
        DependencyProperty.Register("ColorDark", typeof(Brush), typeof(UGrid),
        new PropertyMetadata(new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF3C3C3C")), OnGridSizeChanged));

    private static void OnGridSizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is UGrid grid)
        {
            // 清除缓存，下次重绘时重新生成
            grid._cachedGridBrush = null;
            grid.InvalidateVisual();
        }
    }

    private static object CoerceGridSize(DependencyObject d, object baseValue)
    {
        int size = (int)baseValue;
        return Math.Max(1, Math.Min(size, 100)); // 限制在1-100像素之间
    }
    #endregion

    #region 网格绘制优化
    private readonly DispatcherTimer _redrawTimer;
    private DrawingBrush _cachedGridBrush;
    private int _cachedGridSize;
    private Brush _cachedColorLight;
    private Brush _cachedColorDark;

    private void OnRedrawTimerTick(object sender, EventArgs e)
    {
        _redrawTimer.IsEnabled = false;
        InvalidateVisual();
    }

    protected override void OnRender(DrawingContext drawingContext)
    {
        // 先调用基类方法绘制子元素
        base.OnRender(drawingContext);

        if (ActualWidth <= 0 || ActualHeight <= 0 || GridSize <= 0)
            return;

        // 检查是否需要更新缓存的网格画笔
        if (_cachedGridBrush == null ||
            _cachedGridSize != GridSize ||
            !BrushEquals(_cachedColorLight, ColorLight) ||
            !BrushEquals(_cachedColorDark, ColorDark))
        {
            UpdateCachedGridBrush();
        }

        // 使用缓存的网格画笔绘制背景
        drawingContext.DrawRectangle(_cachedGridBrush, null, new Rect(0, 0, ActualWidth, ActualHeight));
    }

    // 比较两个Brush是否相等
    private bool BrushEquals(Brush a, Brush b)
    {
        if (a == b) return true;
        if (a == null || b == null) return false;

        if (a is SolidColorBrush scbA && b is SolidColorBrush scbB)
        {
            return scbA.Color == scbB.Color &&
                   scbA.Opacity == scbB.Opacity &&
                   scbA.Transform == scbB.Transform;
        }

        return false; // 对于非纯色笔刷，简单认为不相等
    }

    private void UpdateCachedGridBrush()
    {
        // 创建用于平铺的网格单元（2x2网格）
        double tileSize = GridSize * 2;

        // 创建DrawingVisual来绘制网格单元
        DrawingVisual visual = new DrawingVisual();
        using (DrawingContext dc = visual.RenderOpen())
        {
            // 绘制浅色背景
            dc.DrawRectangle(ColorLight, null, new Rect(0, 0, tileSize, tileSize));

            // 绘制深色方块
            dc.DrawRectangle(ColorDark, null, new Rect(GridSize, 0, GridSize, GridSize));
            dc.DrawRectangle(ColorDark, null, new Rect(0, GridSize, GridSize, GridSize));
        }

        // 创建DrawingBrush并设置平铺属性
        _cachedGridBrush = new DrawingBrush(visual.Drawing)
        {
            TileMode = TileMode.Tile,
            Viewport = new Rect(0, 0, tileSize, tileSize),
            ViewportUnits = BrushMappingMode.Absolute,
            Stretch = Stretch.None
        };

        // 冻结画笔（如果可能）以提高性能
        if (_cachedGridBrush.CanFreeze)
        {
            _cachedGridBrush.Freeze();
        }

        // 更新缓存
        _cachedGridSize = GridSize;
        _cachedColorLight = ColorLight;
        _cachedColorDark = ColorDark;
    }
    #endregion

    #region 网格吸附功能
    /// <summary>
    /// 将点吸附到最近的网格点
    /// </summary>
    public Point SnapToGrid(Point point)
    {
        if (!IsSnapToGrid || GridSize <= 0) return point;

        double snappedX = Math.Round(point.X / GridSize) * GridSize;
        double snappedY = Math.Round(point.Y / GridSize) * GridSize;

        return new Point(snappedX, snappedY);
    }
    #endregion

    #region 选择功能（基础实现）
    protected override void OnMouseDown(MouseButtonEventArgs e)
    {
        base.OnMouseDown(e);

        // 清除所有子元素的选择状态
        ClearSelection();
    }

    /// <summary>
    /// 清除所有子元素的选择状态
    /// </summary>
    protected virtual void ClearSelection()
    {
        // 基础实现为空，流程图控件将覆盖此方法
    }
    #endregion
}



/// <summary>
/// 流程图专用画布
/// </summary>
public class FlowChartCanvas : UGrid
{
    #region 构造方法
    public FlowChartCanvas()
    {
        // 初始化流程图专用属性
        InitializeFlowChartFeatures();

        // 设置默认连接线颜色
        ConnectionLineBrush = Brushes.DarkGray;
        ConnectionPointBrush = Brushes.DodgerBlue;
    }

    private void InitializeFlowChartFeatures()
    {
        // 创建选择矩形
        _selectionRect = new Rectangle
        {
            Stroke = Brushes.DodgerBlue,
            StrokeThickness = 1,
            StrokeDashArray = new DoubleCollection { 4, 2 },
            Fill = new SolidColorBrush(Color.FromArgb(50, 30, 144, 255)),
            Visibility = Visibility.Collapsed
        };
        Children.Add(_selectionRect);
        SetZIndex(_selectionRect, 1000); // 确保在最顶层

        // 创建连接点容器
        _connectionPoints = new Dictionary<UIElement, List<ConnectionPoint>>();

        // 创建连接线容器
        _connectionLines = new List<ConnectionLine>();

        // 创建连接点画布
        _connectionPointCanvas = new Canvas();
        Children.Add(_connectionPointCanvas);
        SetZIndex(_connectionPointCanvas, 900); // 在顶层但低于选择矩形

        // 创建连接线画布
        _connectionLineCanvas = new Canvas();
        Children.Add(_connectionLineCanvas);
        SetZIndex(_connectionLineCanvas, 800); // 在顶层但低于连接点
    }
    #endregion

    #region 流程图专用依赖属性
    /// <summary>
    /// 连接线颜色
    /// </summary>
    public Brush ConnectionLineBrush
    {
        get { return (Brush)GetValue(ConnectionLineBrushProperty); }
        set { SetValue(ConnectionLineBrushProperty, value); }
    }
    public static readonly DependencyProperty ConnectionLineBrushProperty =
        DependencyProperty.Register("ConnectionLineBrush", typeof(Brush), typeof(FlowChartCanvas),
        new PropertyMetadata(Brushes.DarkGray, OnConnectionLineBrushChanged));

    private static void OnConnectionLineBrushChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is FlowChartCanvas canvas && e.NewValue is Brush newBrush)
        {
            canvas.UpdateConnectionLinesBrush(newBrush);
        }
    }

    /// <summary>
    /// 连接点颜色
    /// </summary>
    public Brush ConnectionPointBrush
    {
        get { return (Brush)GetValue(ConnectionPointBrushProperty); }
        set { SetValue(ConnectionPointBrushProperty, value); }
    }
    public static readonly DependencyProperty ConnectionPointBrushProperty =
        DependencyProperty.Register("ConnectionPointBrush", typeof(Brush), typeof(FlowChartCanvas),
        new PropertyMetadata(Brushes.DodgerBlue, OnConnectionPointBrushChanged));

    private static void OnConnectionPointBrushChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is FlowChartCanvas canvas && e.NewValue is Brush newBrush)
        {
            canvas.UpdateConnectionPointsBrush(newBrush);
        }
    }

    /// <summary>
    /// 是否显示连接点
    /// </summary>
    public bool ShowConnectionPoints
    {
        get { return (bool)GetValue(ShowConnectionPointsProperty); }
        set { SetValue(ShowConnectionPointsProperty, value); }
    }
    public static readonly DependencyProperty ShowConnectionPointsProperty =
        DependencyProperty.Register("ShowConnectionPoints", typeof(bool), typeof(FlowChartCanvas),
        new PropertyMetadata(false, OnShowConnectionPointsChanged));

    private static void OnShowConnectionPointsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is FlowChartCanvas grid)
        {
            grid.UpdateConnectionPointsVisibility();
        }
    }
    #endregion

    #region 流程图功能实现

    #region 连接点管理
    private  Dictionary<UIElement, List<ConnectionPoint>> _connectionPoints;
    private  Canvas _connectionPointCanvas;

    /// <summary>
    /// 连接点类
    /// </summary>
    public class ConnectionPoint
    {
        public Point Position { get; set; }
        public Ellipse Visual { get; set; }
        public UIElement Owner { get; set; }
        public int Index { get; set; }
    }

    /// <summary>
    /// 添加连接点到元素
    /// </summary>
    public void AddConnectionPoints(UIElement element, params Point[] positions)
    {
        if (!_connectionPoints.ContainsKey(element))
        {
            _connectionPoints[element] = new List<ConnectionPoint>();
        }

        for (int i = 0; i < positions.Length; i++)
        {
            var point = new ConnectionPoint
            {
                Owner = element,
                Position = positions[i],
                Index = i
            };

            // 创建可视化连接点
            var ellipse = new Ellipse
            {
                Width = 8,
                Height = 8,
                Fill = ConnectionPointBrush,
                Stroke = Brushes.White,
                StrokeThickness = 1,
                Tag = point,
                Visibility = ShowConnectionPoints ? Visibility.Visible : Visibility.Collapsed
            };

            // 设置位置
            Canvas.SetLeft(ellipse, positions[i].X - 4);
            Canvas.SetTop(ellipse, positions[i].Y - 4);

            // 添加到连接点画布
            _connectionPointCanvas.Children.Add(ellipse);
            point.Visual = ellipse;
            _connectionPoints[element].Add(point);
        }
    }

    /// <summary>
    /// 更新连接点位置
    /// </summary>
    public void UpdateConnectionPoints(UIElement element)
    {
        if (_connectionPoints.TryGetValue(element, out var points))
        {
            var position = new Point(GetLeft(element), GetTop(element));

            foreach (var point in points)
            {
                // 计算绝对位置
                var absolutePos = new Point(
                    position.X + point.Position.X,
                    position.Y + point.Position.Y);

                Canvas.SetLeft(point.Visual, absolutePos.X - 4);
                Canvas.SetTop(point.Visual, absolutePos.Y - 4);
            }
        }
    }

    /// <summary>
    /// 移除元素的所有连接点
    /// </summary>
    public void RemoveConnectionPoints(UIElement element)
    {
        if (_connectionPoints.TryGetValue(element, out var points))
        {
            foreach (var point in points)
            {
                _connectionPointCanvas.Children.Remove(point.Visual);
            }
            _connectionPoints.Remove(element);
        }
    }

    /// <summary>
    /// 更新连接点可见性
    /// </summary>
    private void UpdateConnectionPointsVisibility()
    {
        var visibility = ShowConnectionPoints ? Visibility.Visible : Visibility.Collapsed;

        foreach (var points in _connectionPoints.Values)
        {
            foreach (var point in points)
            {
                point.Visual.Visibility = visibility;
            }
        }
    }

    /// <summary>
    /// 更新所有连接点颜色
    /// </summary>
    private void UpdateConnectionPointsBrush(Brush brush)
    {
        foreach (var points in _connectionPoints.Values)
        {
            foreach (var point in points)
            {
                point.Visual.Fill = brush;
            }
        }
    }
    #endregion

    #region 连接线管理
    private  List<ConnectionLine> _connectionLines;
    private  Canvas _connectionLineCanvas;

    /// <summary>
    /// 连接线类
    /// </summary>
    public class ConnectionLine
    {
        public ConnectionPoint StartPoint { get; set; }
        public ConnectionPoint EndPoint { get; set; }
        public System.Windows.Shapes.Path Visual { get; set; }
    }

    /// <summary>
    /// 添加连接线
    /// </summary>
    public ConnectionLine AddConnectionLine(ConnectionPoint start, ConnectionPoint end)
    {
        var line = new ConnectionLine
        {
            StartPoint = start,
            EndPoint = end
        };

        // 创建可视化连接线
        var path = new System.Windows.Shapes.Path
        {
            Stroke = ConnectionLineBrush,
            StrokeThickness = 2,
            Tag = line
        };

        // 更新路径
        UpdateConnectionLinePath(line, path);

        _connectionLineCanvas.Children.Add(path);
        line.Visual = path;
        _connectionLines.Add(line);

        return line;
    }

    /// <summary>
    /// 移除连接线
    /// </summary>
    public void RemoveConnectionLine(ConnectionLine line)
    {
        if (line.Visual != null)
        {
            _connectionLineCanvas.Children.Remove(line.Visual);
        }
        _connectionLines.Remove(line);
    }

    /// <summary>
    /// 更新所有连接线位置
    /// </summary>
    public void UpdateConnectionLines()
    {
        foreach (var line in _connectionLines)
        {
            UpdateConnectionLinePath(line, line.Visual);
        }
    }

    /// <summary>
    /// 更新所有连接线颜色
    /// </summary>
    private void UpdateConnectionLinesBrush(Brush brush)
    {
        foreach (var line in _connectionLines)
        {
            if (line.Visual != null)
            {
                line.Visual.Stroke = brush;
            }
        }
    }

    /// <summary>
    /// 更新单条连接线路径
    /// </summary>
    private void UpdateConnectionLinePath(ConnectionLine line, System.Windows.Shapes.Path path)
    {
        // 计算起点绝对位置
        var startPos = new Point(
            GetLeft(line.StartPoint.Owner) + line.StartPoint.Position.X,
            GetTop(line.StartPoint.Owner) + line.StartPoint.Position.Y);

        // 计算终点绝对位置
        var endPos = new Point(
            GetLeft(line.EndPoint.Owner) + line.EndPoint.Position.X,
            GetTop(line.EndPoint.Owner) + line.EndPoint.Position.Y);

        // 创建贝塞尔曲线路径
        var geometry = new PathGeometry();
        var figure = new PathFigure
        {
            StartPoint = startPos,
            IsClosed = false
        };

        // 计算控制点（创建平滑曲线）
        double controlOffset = Math.Max(Math.Abs(endPos.X - startPos.X) / 2, 50);
        var controlPoint1 = new Point(startPos.X + controlOffset, startPos.Y);
        var controlPoint2 = new Point(endPos.X - controlOffset, endPos.Y);

        figure.Segments.Add(new BezierSegment(controlPoint1, controlPoint2, endPos, true));
        geometry.Figures.Add(figure);

        path.Data = geometry;
    }
    #endregion

    #region 连接点吸附功能
    /// <summary>
    /// 将点吸附到最近的连接点
    /// </summary>
    public Point SnapToConnectionPoint(Point point, double maxDistance = 20)
    {
        if (!IsSnapToGrid || maxDistance <= 0) return point;

        double closestDistance = double.MaxValue;
        Point closestPoint = point;

        foreach (var points in _connectionPoints.Values)
        {
            foreach (var cp in points)
            {
                // 计算连接点绝对位置
                var cpPos = new Point(
                    GetLeft(cp.Owner) + cp.Position.X,
                    GetTop(cp.Owner) + cp.Position.Y);

                // 计算距离
                double distance = Point.Subtract(cpPos, point).Length;

                if (distance < maxDistance && distance < closestDistance)
                {
                    closestDistance = distance;
                    closestPoint = cpPos;
                }
            }
        }

        return closestDistance < maxDistance ? closestPoint : point;
    }

    /// <summary>
    /// 获取最近的连接点
    /// </summary>
    public ConnectionPoint GetNearestConnectionPoint(Point point, double maxDistance = 20)
    {
        if (maxDistance <= 0) return null;

        double closestDistance = double.MaxValue;
        ConnectionPoint closestPoint = null;

        foreach (var points in _connectionPoints.Values)
        {
            foreach (var cp in points)
            {
                // 计算连接点绝对位置
                var cpPos = new Point(
                    GetLeft(cp.Owner) + cp.Position.X,
                    GetTop(cp.Owner) + cp.Position.Y);

                // 计算距离
                double distance = Point.Subtract(cpPos, point).Length;

                if (distance < maxDistance && distance < closestDistance)
                {
                    closestDistance = distance;
                    closestPoint = cp;
                }
            }
        }

        return closestDistance < maxDistance ? closestPoint : null;
    }

    /// <summary>
    /// 获取元素的指定索引连接点
    /// </summary>
    public ConnectionPoint GetConnectionPoint(UIElement element, int index)
    {
        if (_connectionPoints.TryGetValue(element, out var points))
        {
            foreach (var point in points)
            {
                if (point.Index == index)
                {
                    return point;
                }
            }
        }
        return null;
    }

    /// <summary>
    /// 显示/隐藏所有连接点
    /// </summary>
    public void SetConnectionPointsVisibility(Visibility visibility)
    {
        foreach (var child in Children)
        {
            if (child is FlowChartNode node)
            {
                node.ConnectionPointsVisibility = visibility;
            }
        }
    }

    #endregion

    #region 选择功能
    private Point _selectionStart;
    private Rectangle _selectionRect;
    private List<UIElement> _selectedElements = new List<UIElement>();

    protected override void OnMouseDown(MouseButtonEventArgs e)
    {
        base.OnMouseDown(e);

        if (e.ChangedButton == MouseButton.Left)
        {
            // 开始选择
            _selectionStart = e.GetPosition(this);
            Canvas.SetLeft(_selectionRect, _selectionStart.X);
            Canvas.SetTop(_selectionRect, _selectionStart.Y);
            _selectionRect.Width = 0;
            _selectionRect.Height = 0;
            _selectionRect.Visibility = Visibility.Visible;

            CaptureMouse();
        }
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        base.OnMouseMove(e);

        if (_selectionRect.Visibility == Visibility.Visible)
        {
            // 更新选择矩形
            Point currentPos = e.GetPosition(this);

            double left = Math.Min(_selectionStart.X, currentPos.X);
            double top = Math.Min(_selectionStart.Y, currentPos.Y);
            double width = Math.Abs(currentPos.X - _selectionStart.X);
            double height = Math.Abs(currentPos.Y - _selectionStart.Y);

            Canvas.SetLeft(_selectionRect, left);
            Canvas.SetTop(_selectionRect, top);
            _selectionRect.Width = width;
            _selectionRect.Height = height;
        }
    }

    protected override void OnMouseUp(MouseButtonEventArgs e)
    {
        base.OnMouseUp(e);

        if (_selectionRect.Visibility == Visibility.Visible && e.ChangedButton == MouseButton.Left)
        {
            // 结束选择
            _selectionRect.Visibility = Visibility.Collapsed;
            ReleaseMouseCapture();

            // 计算选择区域
            Rect selectionArea = new Rect(
                Canvas.GetLeft(_selectionRect),
                Canvas.GetTop(_selectionRect),
                _selectionRect.Width,
                _selectionRect.Height);

            // 清除之前的选择
            ClearSelection();

            // 选择区域内的元素
            foreach (UIElement child in Children)
            {
                if (child == _selectionRect ||
                    child == _connectionPointCanvas ||
                    child == _connectionLineCanvas)
                    continue;

                Point position = new Point(GetLeft(child), GetTop(child));
                Rect elementRect = new Rect(position, child.RenderSize);

                if (selectionArea.IntersectsWith(elementRect))
                {
                    AddToSelection(child);
                }
            }
        }
    }

    /// <summary>
    /// 添加元素到选择集
    /// </summary>
    public void AddToSelection(UIElement element)
    {
        if (!_selectedElements.Contains(element))
        {
            _selectedElements.Add(element);
            // 添加选择效果（例如边框）
            element.Effect = new System.Windows.Media.Effects.DropShadowEffect
            {
                Color = Colors.DodgerBlue,
                BlurRadius = 10,
                ShadowDepth = 0
            };
        }
    }

    /// <summary>
    /// 从选择集移除元素
    /// </summary>
    public void RemoveFromSelection(UIElement element)
    {
        if (_selectedElements.Contains(element))
        {
            _selectedElements.Remove(element);
            element.Effect = null; // 移除选择效果
        }
    }

    /// <summary>
    /// 清除选择集
    /// </summary>
    protected override void ClearSelection()
    {
        foreach (var element in _selectedElements)
        {
            element.Effect = null; // 移除选择效果
        }
        _selectedElements.Clear();
    }

    /// <summary>
    /// 移动选择集
    /// </summary>
    public void MoveSelection(Vector offset)
    {
        foreach (var element in _selectedElements)
        {
            double left = GetLeft(element);
            double top = GetTop(element);

            // 应用网格吸附
            Point newPos = SnapToGrid(new Point(left + offset.X, top + offset.Y));

            SetLeft(element, newPos.X);
            SetTop(element, newPos.Y);

            // 更新连接点和连接线
            UpdateConnectionPoints(element);
        }

        UpdateConnectionLines();
    }

    /// <summary>
    /// 获取当前选中的元素
    /// </summary>
    public IEnumerable<UIElement> SelectedElements => _selectedElements;
    #endregion

    #endregion

    #region 元素添加/移除重写
    protected override void OnVisualChildrenChanged(DependencyObject visualAdded, DependencyObject visualRemoved)
    {
        base.OnVisualChildrenChanged(visualAdded, visualRemoved);

        // 添加元素时自动添加连接点
        if (visualAdded is UIElement elementAdded &&
            elementAdded != _selectionRect &&
            elementAdded != _connectionPointCanvas &&
            elementAdded != _connectionLineCanvas)
        {
            // 默认在四边中点添加连接点
            double width = elementAdded.DesiredSize.Width;
            double height = elementAdded.DesiredSize.Height;

            AddConnectionPoints(elementAdded,
                new Point(width / 2, 0),         // 上
                new Point(width, height / 2),     // 右
                new Point(width / 2, height),     // 下
                new Point(0, height / 2)          // 左
            );
        }

        // 移除元素时自动移除相关连接点
        if (visualRemoved is UIElement elementRemoved)
        {
            RemoveConnectionPoints(elementRemoved);

            // 移除相关连接线
            var linesToRemove = new List<ConnectionLine>();
            foreach (var line in _connectionLines)
            {
                if (line.StartPoint.Owner == elementRemoved ||
                    line.EndPoint.Owner == elementRemoved)
                {
                    linesToRemove.Add(line);
                }
            }

            foreach (var line in linesToRemove)
            {
                RemoveConnectionLine(line);
            }
        }
    }
    #endregion

    #region 连接操作
    private ConnectionPoint _currentConnectionStart;
    private System.Windows.Shapes.Path _currentConnectionPreview;

    /// <summary>
    /// 开始创建连接
    /// </summary>
    public void StartConnection(ConnectionPoint startPoint)
    {
        _currentConnectionStart = startPoint;

        // 创建预览连接线
        _currentConnectionPreview = new System.Windows.Shapes.Path
        {
            Stroke = ConnectionLineBrush,
            StrokeThickness = 2,
            StrokeDashArray = new DoubleCollection { 4, 2 }
        };
        _connectionLineCanvas.Children.Add(_currentConnectionPreview);

        // 捕获鼠标
        Mouse.Capture(this);
    }

    /// <summary>
    /// 更新连接预览
    /// </summary>
    public void UpdateConnectionPreview(Point endPosition)
    {
        if (_currentConnectionStart == null || _currentConnectionPreview == null)
            return;

        // 计算起点绝对位置
        var startPos = new Point(
            GetLeft(_currentConnectionStart.Owner) + _currentConnectionStart.Position.X,
            GetTop(_currentConnectionStart.Owner) + _currentConnectionStart.Position.Y);

        // 创建预览路径
        var geometry = new PathGeometry();
        var figure = new PathFigure
        {
            StartPoint = startPos,
            IsClosed = false
        };

        // 计算控制点
        double controlOffset = Math.Max(Math.Abs(endPosition.X - startPos.X) / 2, 50);
        var controlPoint1 = new Point(startPos.X + controlOffset, startPos.Y);
        var controlPoint2 = new Point(endPosition.X - controlOffset, endPosition.Y);

        figure.Segments.Add(new BezierSegment(controlPoint1, controlPoint2, endPosition, true));
        geometry.Figures.Add(figure);

        _currentConnectionPreview.Data = geometry;
    }

    /// <summary>
    /// 完成连接创建
    /// </summary>
    public ConnectionLine CompleteConnection(ConnectionPoint endPoint)
    {
        if (_currentConnectionStart == null || endPoint == null)
            return null;

        // 移除预览线
        if (_currentConnectionPreview != null)
        {
            _connectionLineCanvas.Children.Remove(_currentConnectionPreview);
            _currentConnectionPreview = null;
        }

        // 创建实际连接线
        var connectionLine = AddConnectionLine(_currentConnectionStart, endPoint);
        _currentConnectionStart = null;

        // 释放鼠标捕获
        Mouse.Capture(null);

        return connectionLine;
    }

    /// <summary>
    /// 取消连接创建
    /// </summary>
    public void CancelConnection()
    {
        if (_currentConnectionPreview != null)
        {
            _connectionLineCanvas.Children.Remove(_currentConnectionPreview);
            _currentConnectionPreview = null;
        }
        _currentConnectionStart = null;

        // 释放鼠标捕获
        Mouse.Capture(null);
    }
    #endregion



    
}

/// <summary>
/// 流程图节点控件
/// </summary>
public class FlowChartNode : ContentControl
{
    static FlowChartNode()
    {
        DefaultStyleKeyProperty.OverrideMetadata(
            typeof(FlowChartNode),
            new FrameworkPropertyMetadata(typeof(FlowChartNode)));
    }

    #region 依赖属性
    /// <summary>
    /// 节点类型
    /// </summary>
    public FlowNodeType NodeType
    {
        get { return (FlowNodeType)GetValue(NodeTypeProperty); }
        set { SetValue(NodeTypeProperty, value); }
    }
    public static readonly DependencyProperty NodeTypeProperty =
        DependencyProperty.Register("NodeType", typeof(FlowNodeType), typeof(FlowChartNode),
        new PropertyMetadata(FlowNodeType.Process, OnNodeTypeChanged));

    private static void OnNodeTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is FlowChartNode node)
        {
            node.UpdateAppearance();
        }
    }

    /// <summary>
    /// 连接点半径
    /// </summary>
    public double ConnectionPointRadius
    {
        get { return (double)GetValue(ConnectionPointRadiusProperty); }
        set { SetValue(ConnectionPointRadiusProperty, value); }
    }
    public static readonly DependencyProperty ConnectionPointRadiusProperty =
        DependencyProperty.Register("ConnectionPointRadius", typeof(double), typeof(FlowChartNode),
        new PropertyMetadata(4.0));

    /// <summary>
    /// 连接点可见性
    /// </summary>
    public Visibility ConnectionPointsVisibility
    {
        get { return (Visibility)GetValue(ConnectionPointsVisibilityProperty); }
        set { SetValue(ConnectionPointsVisibilityProperty, value); }
    }
    public static readonly DependencyProperty ConnectionPointsVisibilityProperty =
        DependencyProperty.Register("ConnectionPointsVisibility", typeof(Visibility), typeof(FlowChartNode),
        new PropertyMetadata(Visibility.Collapsed));
    #endregion

    #region 连接点位置
    public Point GetConnectionPoint(int index)
    {
        switch (index)
        {
            case 0: // 上
                return new Point(ActualWidth / 2, 0);
            case 1: // 右
                return new Point(ActualWidth, ActualHeight / 2);
            case 2: // 下
                return new Point(ActualWidth / 2, ActualHeight);
            case 3: // 左
                return new Point(0, ActualHeight / 2);
            default:
                return new Point(ActualWidth / 2, ActualHeight / 2);
        }
    }
    #endregion

    #region 外观更新
    private void UpdateAppearance()
    {
        // 根据节点类型更新默认颜色
        switch (NodeType)
        {
            case FlowNodeType.Start:
                Background = new SolidColorBrush(Color.FromRgb(0x4C, 0xAF, 0x50));
                BorderBrush = new SolidColorBrush(Color.FromRgb(0x2E, 0x7D, 0x32));
                Foreground = Brushes.White;
                break;

            case FlowNodeType.End:
                Background = new SolidColorBrush(Color.FromRgb(0xF4, 0x43, 0x36));
                BorderBrush = new SolidColorBrush(Color.FromRgb(0xC6, 0x28, 0x28));
                Foreground = Brushes.White;
                break;

            case FlowNodeType.Process:
                Background = new SolidColorBrush(Color.FromRgb(0x21, 0x96, 0xF3));
                BorderBrush = new SolidColorBrush(Color.FromRgb(0x0D, 0x47, 0xA1));
                Foreground = Brushes.White;
                break;

            case FlowNodeType.Decision:
                Background = new SolidColorBrush(Color.FromRgb(0xFF, 0xC1, 0x07));
                BorderBrush = new SolidColorBrush(Color.FromRgb(0xE6, 0x51, 0x00));
                Foreground = new SolidColorBrush(Color.FromRgb(0xE6, 0x51, 0x00));
                break;

            case FlowNodeType.InputOutput:
                Background = new SolidColorBrush(Color.FromRgb(0x9C, 0x27, 0xB0));
                BorderBrush = new SolidColorBrush(Color.FromRgb(0x6A, 0x1B, 0x9A));
                Foreground = Brushes.White;
                break;
        }
    }
    #endregion

    #region 连接点渲染
    protected override void OnRender(DrawingContext drawingContext)
    {
        base.OnRender(drawingContext);

        // 如果连接点可见，绘制连接点
        if (ConnectionPointsVisibility == Visibility.Visible)
        {
            double radius = ConnectionPointRadius;
            Brush fill = new SolidColorBrush(Color.FromRgb(0x1E, 0x90, 0xFF));
            Brush stroke = Brushes.White;

            // 绘制四个连接点（上、右、下、左）
            DrawConnectionPoint(drawingContext, new Point(ActualWidth / 2, 0), radius, fill, stroke);
            DrawConnectionPoint(drawingContext, new Point(ActualWidth, ActualHeight / 2), radius, fill, stroke);
            DrawConnectionPoint(drawingContext, new Point(ActualWidth / 2, ActualHeight), radius, fill, stroke);
            DrawConnectionPoint(drawingContext, new Point(0, ActualHeight / 2), radius, fill, stroke);
        }
    }

    private void DrawConnectionPoint(DrawingContext dc, Point center, double radius, Brush fill, Brush stroke)
    {
        dc.DrawEllipse(fill, new Pen(stroke, 1), center, radius, radius);
    }
    #endregion
}

/// <summary>
/// 节点类型
/// </summary>
public enum FlowNodeType
{
    /// <summary>
    /// 开始节点
    /// </summary>
    Start,

    /// <summary>
    /// 结束节点
    /// </summary>
    End,

    /// <summary>
    /// 处理节点
    /// </summary>
    Process,

    /// <summary>
    /// 决策节点
    /// </summary>
    Decision,

    /// <summary>
    /// 输入/输出节点
    /// </summary>
    InputOutput
}